#include <buola/chart/cplot.h>

#include <buola/image/cgc.h>

namespace buola { namespace chart {

//////////////////////////////////////////////////////////
////////////////// CPlot::SPointDrawer ///////////////////
//////////////////////////////////////////////////////////

CPlot::SPointDrawer::SPointDrawer(img::CGC *pGC,ePointShape pShape,EStyle pStyle)
    :   mGC(pGC),
        mShape(pShape),
        mDiameter(5.0),
        mColor(std::wstring(L"black")),
        mFillColor(std::wstring(L"white")),
        mStyle(pStyle)
{
    mGC->SetSource(mColor);

    switch(mShape)
    {
    case POINT:
        mGC->SetLineWidth(mDiameter);
        mGC->SetLineCap(img::ELineCap::ROUND);
        break;
    default:
        mGC->SetLineWidth(1.5);
    }
}

CPlot::SPointDrawer::~SPointDrawer()
{
    switch(mShape)
    {
    case POINT:
        mGC->SetLineCap(img::ELineCap::BUTT);
        break;
    default:
        break;
    }
}

void CPlot::SPointDrawer::Draw(const CPoint_d &pPos)
{
    switch(mShape)
    {
    case POINT:
        mGC->Path().MoveTo(pPos);
        mGC->Path().LineTo(pPos);
        mGC->StrokePath();
        break;
    case SQUARE:
        mGC->Path().Rect(pPos-CPoint_d(1,1)*(mDiameter/sqrt(2.0)),CSize_d(2,2)*(mDiameter/sqrt(2.0)));
        if(mStyle&POINTFILL)
        {
            mGC->SetSource(mFillColor);
            mGC->FillPath(true);
            mGC->SetSource(mColor);
        }
        mGC->StrokePath();
        break;
    case CIRCLE:
        mGC->Path().Arc(pPos,mDiameter/2);
        if(mStyle&POINTFILL)
        {
            mGC->SetSource(mFillColor);
            mGC->FillPath(true);
            mGC->SetSource(mColor);

        }
        mGC->StrokePath();
        break;
    case TRIANGLE:
        mGC->Path().MoveTo(CPoint_d(pPos.x,pPos.y-mDiameter/2));
        mGC->Path().LineTo(CPoint_d(pPos.x-sin(M_PI/3)*mDiameter/2,
                            pPos.y+cos(M_PI/3)*mDiameter/2));
        mGC->Path().LineTo(CPoint_d(pPos.x+sin(M_PI/3)*mDiameter/2,
                            pPos.y+cos(M_PI/3)*mDiameter/2));
        mGC->Path().Close();
        if(mStyle&POINTFILL)
        {
            mGC->SetSource(mFillColor);
            mGC->FillPath(true);
            mGC->SetSource(mColor);
        }
        mGC->StrokePath();
        break;
    case CROSS:
        mGC->Path().MoveTo(CPoint_d(pPos.x-mDiameter/2,pPos.y));
        mGC->Path().LineTo(CPoint_d(pPos.x+mDiameter/2,pPos.y));
        mGC->Path().MoveTo(CPoint_d(pPos.x,pPos.y-mDiameter/2));
        mGC->Path().LineTo(CPoint_d(pPos.x,pPos.y+mDiameter/2));
        mGC->StrokePath();
        break;
    default:
        break;
    }
}

void CPlot::SPointDrawer::SetLineWidth(double pWidth)
{
    if(mShape!=POINT)
    {
        mGC->SetLineWidth(pWidth);
    }
}

void CPlot::SPointDrawer::SetColor(const img::CColor &pColor)
{
    mColor=pColor;
    mGC->SetSource(pColor);
}

void CPlot::SPointDrawer::SetFillColor(const img::CColor &pColor)
{
    mFillColor=pColor;
}

void CPlot::SPointDrawer::SetDiameter(double pDiameter)
{
    mDiameter=pDiameter;

    if(mShape==POINT)
    {
        mGC->SetLineWidth(mDiameter);
    }
}


CPlot::CPlot()
    :   mStyle(STYLE_NONE)
{
}

CPlot::~CPlot()
{
}

void CPlot::SetStyle(EStyle pStyle)
{
    mStyle=pStyle;
}

/*namespace chart*/ } /*namespace buola*/ }
